package ee.difference.principal;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ee.difference.beans.PropertyDescriptorEntry;

public class DifferenceAnalyzer {

	public List<Difference<PropertyDescriptorEntry>> analyzeBeanInfoBaseDefference(Class<?> left, Class<?> right) throws IntrospectionException{
		
		BeanInfo infoLeft = Introspector.getBeanInfo(left);
		BeanInfo infoRight = Introspector.getBeanInfo(right);
		
		List<PropertyDescriptorEntry> propertiesLeft = new ArrayList<PropertyDescriptorEntry>();
		List<PropertyDescriptorEntry> propertiesRight = new ArrayList<PropertyDescriptorEntry>();
		
		for(PropertyDescriptor prop :infoLeft.getPropertyDescriptors() ){
			propertiesLeft.add(new PropertyDescriptorEntry(prop));
		}
		
		for(PropertyDescriptor prop :infoRight.getPropertyDescriptors() ){
			propertiesRight.add(new PropertyDescriptorEntry(prop));
		}
		
		Collections.sort(propertiesLeft);
		Collections.sort(propertiesRight);
		
		List<Difference<PropertyDescriptorEntry>> difference = sequentialDiff(propertiesLeft, propertiesRight);
		
		return difference;
		
	}

	private <DE extends DiffEntry<DE>> List<Difference<DE>> sequentialDiff(
			List<DE> propertiesLeft,
			List<DE> propertiesRight) {
		Iterator<DE> leftEntries = propertiesLeft.iterator();
		Iterator<DE> rightEntries = propertiesRight.iterator();
		DE leftEntry	= leftEntries.next();
		DE rightEntry	= rightEntries.next();
		
		ArrayList<Difference<DE>> diff = new ArrayList<Difference<DE>>();
		
		
		log("-------------------------- + --------------------------");
		while(leftEntries.hasNext() && rightEntries.hasNext()){
			
			if(leftEntry.compareTo(rightEntry)<0){
				diff.add(new Difference<DE>(leftEntry, null));
				leftEntry	= leftEntries.next();
				continue;
			}
			
			if(leftEntry.compareTo(rightEntry)>0){
				diff.add(new Difference<DE>(null, rightEntry));
				rightEntry	= rightEntries.next();
				continue;
			}
			
			// equals
			diff.add(new Difference<DE>(leftEntry, rightEntry));
			leftEntry	= leftEntries.next();
			rightEntry	= rightEntries.next();
			
		}
		log("-------------------------- * --------------------------");
		return diff;
	}

	private void log(String string) {
		System.out.println(string);
		
	}

}
